// 在size发生变化的时候，触发回调函数
let map = new WeakMap();
const obj = {
    el: null
}
const control = {
    controller: null
}

const ob = new ResizeObserver((entries) => {
    console.log('ResizeObserver');
    for (const entry of entries) {
        // 获取 DOM
        let handler = map.get(obj);
        if (handler) {
            changeElementStyle(entry.target, handler)
            handler.method()
        }
    }
});

const vResize = {
    mounted: (el, binding) => {
        console.log('el,binding :>> ', binding);
        obj.el = el
        const bind = binding.modifiers
        let modifiersItem = (Object.entries(bind) || []).map(it => it[0])
        // 留存必要信息
        let content = {
            cssVar: '',
            width: '',
            height: '',
        }
        modifiersItem.forEach(item => {
            if (item.split(':').length < 2) {
                content.cssVar = item
            } else {
                if (item.includes('width')) {
                    content.width = item.replace('width', '').replace(':', '') - 0
                } else if (item.includes('height')) {
                    content.height = item.replace('height', '').replace(':', '') - 0
                }
            }
        })
        // 监听 el 元素尺寸变化
        map.set(obj, {
            method: binding.value,
            ...content
        });
        ob.observe(el);

        const controller = new AbortController();
        // 设置对象，作为对象名
        // 这种方式可以有效移除监听后，还可以重新加回监听
        control.controller = controller
        map.set(control, controller)    // 这里 controller 才是对象值
        window.addEventListener('resize', debounce(() => {
            let handler = map.get(obj);
            changeElementStyle(obj.el, handler)
            handler.method()
        }, 500), {
            signal: map.get(control).signal, // map.get(control) 即是 controller
        })
    },
    unmounted: (el) => {
        // 取消监听
        ob.unobserve(el);
        // 移除监听
        map.get(control).abort()
    },
};

export function setResize(app) {
    app.directive("dyxSpecialMapResize", vResize);
}

/**
 * 防抖函数
 * @param {T} fn
 * @param {number} delay
 * @return
 */
function debounce(fn, delay = 100) {
    let timer = null;
    return function (...args) {
        clearTimeout(timer);
        timer = setTimeout(
            () => {
                typeof fn === "function" && fn.apply(null, args);
                clearTimeout(timer);
            },
            delay > 16 ? delay : 100
        );
    };
}

function changeElementStyle(el, handler) {
    let scales = getComputedStyle(document.documentElement).getPropertyValue(handler.cssVar)
    el.style.width = handler.width * scales + 'px'
    el.style.height = handler.height * scales + 'px'
    el.style.transformOrigin = 'left top'
    el.style.transform = `scale(calc(1 / ${scales}))`
}